package com.syni.mdd.yhd.common.all.service;

import com.syni.mdd.yhd.common.all.constants.Constants;
import com.syni.mdd.yhd.common.all.constants.ResultCode;
import com.syni.mdd.yhd.common.all.constants.ResultMsg;
import com.syni.mdd.yhd.common.all.dao.jpa.BmsDxCommentDao;
import com.syni.mdd.yhd.common.all.entity.*;
import com.syni.mdd.yhd.common.all.entity.user.BmsUser;
import com.syni.mdd.yhd.common.all.listen.comment.CommentEvent;
import com.syni.mdd.yhd.common.all.service.impl.BaseService;
import com.syni.mdd.yhd.common.all.utils.SpecificationUtils;
import com.syni.mdd.yhd.common.all.utils.StringUtils;
import com.syni.mdd.yhd.common.all.utils.TokenManager;
import com.syni.mdd.sjb.common.component.utils.common.utils.ResultMapHelper;
import com.syni.mdd.sjb.common.component.utils.redis.utils.RedisTemplateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @className BmsUserOperationLogService
 * @description TOO
 * @Author cfx
 * @DATE 2019/4/9 12:04
 * @VERSION 1.0
 **/
@Service
public class BmsDxCommentService extends BaseService<BmsDxComment, Integer> {

    //标记是
    final static int trueStatus = 1;

    @Autowired
    BmsDxCommentDao bmsDxCommentDao;

    @Autowired
    BmsVideoService bmsVideoService;

    @Autowired
    BmsUserService bmsUserService;

    @Autowired
    BmsDxAnswerService bmsDxAnswerService;

    @Autowired
    BmsUserVideoService bmsUserVideoService;

    @Autowired
    BmsDxNewsService bmsDxNewsService;

    @Autowired
    BmsDxClientRoleService bmsDxClientRoleService;

    @Autowired
    BmsUserBusinessAuthService bmsUserBusinessAuthService;

    @Autowired
    BmsBusinessService bmsBusinessService;

    @Override
    public BmsDxCommentDao getBaseDao() {
        return bmsDxCommentDao;
    }

    public Map<Integer,Integer> countVideoCommentNum(Set<Integer> videoIds){
        Map<Integer,Integer> resultMap = new HashMap<>();
        List<Map<String,Object>> videoCommentList = bmsDxCommentDao.countVideoCommentNum(videoIds);
        Map<Integer,Integer> videoAnswerMap = bmsDxAnswerService.countVideoAnswer(videoIds);
        if(videoCommentList != null && videoCommentList.size() > 0){
            for(Map<String,Object> objectMap : videoCommentList){
                Integer num = Integer.parseInt(objectMap.get("num").toString());
                Integer videoId = Integer.parseInt(objectMap.get("bms_video_id").toString());
                if(videoAnswerMap.containsKey(videoId)){
                    num += videoAnswerMap.get(videoId);
                }
                resultMap.put(videoId,num);
            }
        }
        return resultMap;
    }

    public Map<String, Object> findVideoComment(Integer videoId,Integer pageNum,
                                                Integer pageSize,Integer commentId) {
        Map<String,Object> userDataMap = new HashMap<>();
        BmsVideo bmsVideo = bmsVideoService.checkVideoExist(videoId);
        if(bmsVideo == null){
            return ResultMapHelper.result(ResultCode.CODE_VIDEO_NO_EXIST,"视频不存在");
        }
        pageNum  = pageNum < 0 ? 1 : pageNum;
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize, Sort.Direction.DESC, "newTime");
        Map<String,Object> conditionMap = new HashMap<>();
        conditionMap.put("bmsVideoId",videoId);
        if(commentId != null){
            conditionMap.put("id_NEQ",commentId);
        }
        Page<BmsDxComment> bmsDxCommentPage = bmsDxCommentDao.findAll(new SpecificationUtils(conditionMap),pageable);
        List<BmsDxComment> bmsDxComments = new LinkedList<>();
        bmsDxComments.addAll(bmsDxCommentPage.getContent());
        if(commentId != null){
            Optional<BmsDxComment> optionalBmsDxComment = bmsDxCommentDao.findById(commentId);
            if(optionalBmsDxComment.isPresent()){
                BmsDxComment bmsDxComment = optionalBmsDxComment.get();
                bmsDxComments.add(0,bmsDxComment);
            }
        }
        userDataMap.put("count",bmsDxCommentPage.getTotalElements());
        userDataMap.put("childCommentsNum",Constants.COMMON_FLAG_FALSE_INT);
        Set<Integer> videoIds = new HashSet<>();
        videoIds.add(videoId);
        Map<Integer,Integer> childCommentsNums = bmsDxAnswerService.countVideoAnswer(videoIds);
        if(childCommentsNums.containsKey(videoId)) {
            userDataMap.put("childCommentsNum",childCommentsNums.get(videoId));
        }
        //System.out.println(bmsDxComments);
        if(bmsDxComments != null && bmsDxComments.size() > 0){
            BmsUserVideo bmsUserVideo = getBmsDxCommentsVideoMap(bmsDxComments);
            for(BmsDxComment bmsDxComment : bmsDxComments){
                //设置评论
                if(bmsUserVideo != null){
                    if(bmsDxComment.getBmsUserId().intValue() == bmsUserVideo.getUserId().intValue()){
                        bmsDxComment.setIsAuthor(trueStatus);
                    }
                }
                setIsBusinessAndBusinessAuth(bmsDxComment);
                setCommentNickNameAndHeadImg(bmsDxComment);
                //获取子评论
                List<BmsDxAnswer> bmsDxAnswers = bmsDxComment.getBmsDxAnswerList();
                Collections.sort(bmsDxAnswers, new Comparator<BmsDxAnswer>() {
                    @Override
                    public int compare(BmsDxAnswer o1, BmsDxAnswer o2) {
                        if(o1.getNewTime().getTime() > o2.getNewTime().getTime()){
                            return -1;
                        }
                        return 1;
                    }
                });
                Map<Integer,BmsDxAnswer> answerMap = new HashMap<>();
                if(bmsDxAnswers != null && bmsDxAnswers.size() > 0){
                    for(BmsDxAnswer bmsDxAnswer : bmsDxAnswers){
                        answerMap.put(bmsDxAnswer.getId(),bmsDxAnswer);
                    }
                    for(BmsDxAnswer bmsDxAnswer : bmsDxAnswers){
                        //设置是否为作者评论
                        if(bmsUserVideo != null){
                            if(bmsDxAnswer.getBmsUserId().intValue() == bmsUserVideo.getUserId().intValue()){
                                bmsDxAnswer.setIsAuthor(trueStatus);
                            }
                        }
                        setIsBusinessAndBusinessAuth(bmsDxAnswer);
                        //设置子评论头像
                        setAnswerNickNameAndHeadImg(bmsDxAnswer);
                        if(bmsDxAnswer.getBmsAnswerId() != null){
                            //设置回复对象
                            if(answerMap.containsKey(bmsDxAnswer.getBmsAnswerId())){
                                BmsDxAnswer bmsDxAnswerReply = answerMap.get(bmsDxAnswer.getBmsAnswerId());
                                handleDxAnswer(bmsDxAnswer,bmsDxComment,bmsDxAnswerReply);
                            }
                        }
                    }
                }
            }
        }
        return ResultMapHelper.success(bmsDxComments,userDataMap,"获取成功");
    }

    public void setIsBusinessAndBusinessAuth(BmsDxComment bmsDxComment){
        if(bmsDxComment.getFromOrigin().intValue() == Constants.BUSINESS_CLIENT){
            bmsDxComment.setIsBussiness(Constants.COMMON_FLAG_TRUE_INT);
            BmsUserBusinessAuth bmsUserBusinessAuth = bmsUserBusinessAuthService.findByUserId(bmsDxComment.getBmsUserId());
            if(bmsUserBusinessAuth != null && bmsUserBusinessAuth.getBmsBusiness() != null){
                if(bmsUserBusinessAuth.getBmsBusiness().getIsAuth().intValue() == trueStatus){
                    bmsDxComment.setIsBussinessAuth(trueStatus);
                }
            }
        }
    }

    public void setIsBusinessAndBusinessAuth(BmsDxAnswer bmsDxAnswer){
        if(bmsDxAnswer.getFromOrigin().intValue() == Constants.BUSINESS_CLIENT){
            bmsDxAnswer.setIsBussiness(Constants.COMMON_FLAG_TRUE_INT);
            BmsUserBusinessAuth bmsUserBusinessAuth = bmsUserBusinessAuthService.findByUserId(bmsDxAnswer.getBmsUserId());
            if(bmsUserBusinessAuth != null && bmsUserBusinessAuth.getBmsBusiness() != null){
                if(bmsUserBusinessAuth.getBmsBusiness().getIsAuth().intValue() == trueStatus){
                    bmsDxAnswer.setIsBussinessAuth(trueStatus);
                }
            }
        }
    }

    public void setCommentNickNameAndHeadImg(BmsDxComment bmsDxComment){
        bmsDxComment.setNickName("");
        bmsDxComment.setHeadImgUrl("");
        if(bmsDxComment.getFromOrigin() == Constants.ADMIN_CLIENT){

        }else if(bmsDxComment.getFromOrigin() == Constants.USER_CLIENT){
            BmsUser bmsUser = TokenManager.getUser(bmsDxComment.getBmsUserId());
            if(bmsUser != null) {
                String loginName = bmsUser.getLoginName();
                if(StringUtils.isBlank(loginName)){
                    loginName = bmsUser.getSystemUser().getLoginName();
                }
                if(StringUtils.isNotBlank(loginName)){
                    bmsDxComment.setNickName(loginName);
                }
                String headImg = bmsUser.getHeadImg();
                if(StringUtils.isNotBlank(headImg)){
                    bmsDxComment.setHeadImgUrl(headImg);
                }
            }
        }else if(bmsDxComment.getFromOrigin() == Constants.BUSINESS_CLIENT){
            if(bmsDxComment.getBmsBusinessId() != null) {
                Optional<BmsBusiness> businessOptional = bmsBusinessService.getBaseDao().findById(bmsDxComment.getBmsBusinessId());
                if(businessOptional.isPresent()){
                    BmsBusiness business = businessOptional.get();
                    String loginName = business.getVendorName();
                    if(StringUtils.isNotBlank(loginName)){
                        bmsDxComment.setNickName(loginName);
                    }
                    String logoUrl = business.getLogoUrl();
                    if(StringUtils.isNotBlank(logoUrl)){
                        bmsDxComment.setHeadImgUrl(logoUrl);
                    }
                }
            }
        }
    }

    public void setAnswerNickNameAndHeadImg(BmsDxAnswer bmsDxAnswer){
        bmsDxAnswer.setNickName("");
        bmsDxAnswer.setHeadImgUrl("");
        if(bmsDxAnswer.getFromOrigin() == Constants.ADMIN_CLIENT){

        }else if(bmsDxAnswer.getFromOrigin() == Constants.USER_CLIENT){
            BmsUser bmsUser = TokenManager.getUser(bmsDxAnswer.getBmsUserId());
            if(bmsUser != null) {
                String loginName = bmsUser.getLoginName();
                if(StringUtils.isBlank(loginName)){
                    loginName = bmsUser.getSystemUser().getLoginName();
                }
                if(StringUtils.isNotBlank(loginName)){
                    bmsDxAnswer.setNickName(loginName);
                }
                String headImg = bmsUser.getHeadImg();
                if(StringUtils.isNotBlank(headImg)){
                    bmsDxAnswer.setHeadImgUrl(headImg);
                }
            }
        }else if(bmsDxAnswer.getFromOrigin() == Constants.BUSINESS_CLIENT){
            if(bmsDxAnswer.getBmsBusinessId() != null) {
                Optional<BmsBusiness> businessOptional = bmsBusinessService.getBaseDao().findById(bmsDxAnswer.getBmsBusinessId());
                if(businessOptional.isPresent()){
                    BmsBusiness business = businessOptional.get();
                    String loginName = business.getVendorName();
                    if(StringUtils.isNotBlank(loginName)){
                        bmsDxAnswer.setNickName(loginName);
                    }
                    String logoUrl = business.getLogoUrl();
                    if(StringUtils.isNotBlank(logoUrl)){
                        bmsDxAnswer.setHeadImgUrl(logoUrl);
                    }
                }
            }
        }
    }

    public BmsUserVideo getBmsDxCommentsVideoMap(List<BmsDxComment> bmsDxComments) {
        BmsUserVideo bmsUserVideo = null;
        if (bmsDxComments != null && bmsDxComments.size() > 0) {
            Set<Integer> videoIds = new HashSet<>();
            videoIds.add(bmsDxComments.get(0).getBmsVideoId());
            List<BmsUserVideo> bmsUserVideos = bmsUserVideoService.getByVideoIds(videoIds);
            if(bmsUserVideos.size() > 0) {
                bmsUserVideo = bmsUserVideos.get(0);
            }
        }
        return bmsUserVideo;
    }

    @Transactional
    public Map<String, Object> doVideoComment(Integer userId,Integer businessId,Integer videoId,String content,Integer commentId,Integer answerId) {
        Optional<BmsUser> bo = bmsUserService.getBaseDao().findById(userId);
        if(!bo.isPresent()){
            return ResultMapHelper.result(ResultCode.USER_TOKEN_INVALID, ResultMsg.MSG_USER_TOKEN_EXPIRE);
        }
        BmsUser bmsUser = bo.get();
        if(bmsUser.getIsComment() != null && bmsUser.getIsComment() == Constants.COMMON_FLAG_TRUE_INT){
            return ResultMapHelper.result(ResultCode.CODE_ERROR_100, ResultMsg.MSG_USER_NO_COMMENT);
        }
        final int add = 1;
        Optional<BmsVideo> bmsVideoOptional = bmsVideoService.getBaseDao().findById(videoId);
        if(!bmsVideoOptional.isPresent()){
            return ResultMapHelper.failure("评论失败,该视频不存在");
        }
        BmsVideo bmsVideo = bmsVideoOptional.get();
        Object result = null;
        Integer fromOrgin = Constants.USER_CLIENT;
        if(businessId != null){
            fromOrgin = Constants.BUSINESS_CLIENT;
        }
        BmsDxComment bmsDxComment = null;
        if(commentId == null && answerId == null) {
            //普通评论
            bmsDxComment = new BmsDxComment();
            bmsDxComment.setBmsVideoId(videoId);
            bmsDxComment.setBmsUserId(userId);
            bmsDxComment.setContent(content);
            bmsDxComment.setNewTime(new Date());
            bmsDxComment.setFromOrigin(fromOrgin);
            bmsDxComment.setBmsBusinessId(businessId);
            bmsDxCommentDao.save(bmsDxComment);
            handleDxComment(bmsDxComment);
            result = bmsDxComment;
            //将评论的视频用户加入消息通知
            addGeneralCommentToNews(userId,bmsVideo,bmsDxComment);
        } else{
            if(commentId != null){
                //回复
                Optional<BmsDxComment> bmsDxCommentOp = bmsDxCommentDao.findById(commentId);
                if(!bmsDxCommentOp.isPresent()){
                    return ResultMapHelper.failure("回复失败,该评论不存在");
                }
                bmsDxComment = bmsDxCommentOp.get();
                BmsDxAnswer replyAnswer = null;
                if(answerId != null){
                    Optional<BmsDxAnswer> replyAnswerOp = bmsDxAnswerService.getBaseDao().findById(answerId);
                    if(!replyAnswerOp.isPresent()){
                        return ResultMapHelper.failure("回复失败,该回复不存在");
                    }
                    replyAnswer = replyAnswerOp.get();
                }
                BmsDxAnswer bmsDxAnswer = new BmsDxAnswer();
                bmsDxAnswer.setBmsDxCommentId(commentId);
                bmsDxAnswer.setBmsAnswerId(answerId);
                bmsDxAnswer.setBmsUserId(userId);
                bmsDxAnswer.setContent(content);
                bmsDxAnswer.setNewTime(new Date());
                bmsDxAnswer.setFromOrigin(fromOrgin);
                bmsDxAnswer.setBmsBusinessId(businessId);
                bmsDxAnswerService.save(bmsDxAnswer);
                handleDxAnswer(bmsDxAnswer,bmsDxComment,replyAnswer);
                result = bmsDxAnswer;
                //将回复加入消息通知表
                if(bmsDxAnswer.getBmsAnswerId() == null) {
                    addFirstLevelToNews(bmsVideo,bmsDxComment, bmsDxAnswer);
                }else {
                    addSecondLevelToNews(bmsVideo,replyAnswer,bmsDxAnswer);
                }
            }
        }
        if(bmsDxComment == null || bmsDxComment.getId() == null){
            return ResultMapHelper.failure("评论失败");
        }
        addCommentNumToRedis(videoId, add);
        return ResultMapHelper.success(result,"评论成功");

    }

    /**
     * @Description 评论加入消息表
     * @Author: cfx
     * @Date: 2019/6/30
     */
    public void addGeneralCommentToNews(Integer userId,BmsVideo bmsVideo,BmsDxComment bmsDxComment){
        BmsCommonService.getApplicationContext().
                publishEvent(new CommentEvent("generalComment",bmsDxComment,bmsVideo,userId));
    }

    /**
     * @Description 回复加入消息表
     * @Author: cfx
     * @Date: 2019/6/30
     */
    public void addFirstLevelToNews(BmsVideo bmsVideo,BmsDxComment bmsDxComment,BmsDxAnswer bmsDxAnswer){
        BmsCommonService.getApplicationContext().
                publishEvent(new CommentEvent("answerComment",bmsDxComment,bmsVideo,bmsDxAnswer));
    }

    /**
     * @Description 回复的回复加入消息表
     * @Author: cfx
     * @Date: 2019/6/30
     */
    public void addSecondLevelToNews(BmsVideo bmsVideo,
                                     BmsDxAnswer replyAnswer,BmsDxAnswer bmsDxAnswer) {
        BmsCommonService.getApplicationContext().
                publishEvent(new CommentEvent("answerToAnswer",bmsVideo,replyAnswer,bmsDxAnswer));
    }


    public void addCommentNumToRedis(Integer videoId,Integer status) {
        RedisTemplateUtils.getRedisTemplate().opsForZSet().incrementScore(Constants.REDIS_KEY_LIKEDK,"comment:" + videoId,status);
    }

    public void handleDxComment(BmsDxComment bmsDxComment) {
        List<BmsDxComment> bmsDxComments = new LinkedList<>();
        bmsDxComments.add(bmsDxComment);
        BmsUserVideo bmsUserVideo = getBmsDxCommentsVideoMap(bmsDxComments);
        if(bmsUserVideo != null){
            if(bmsDxComment.getBmsUserId().intValue() == bmsUserVideo.getUserId().intValue()){
                bmsDxComment.setIsAuthor(trueStatus);
            }
        }
        //设置是否是商家/是否是认证商家
        setIsBusinessAndBusinessAuth(bmsDxComment);
        setCommentNickNameAndHeadImg(bmsDxComment);
    }

    public void handleDxAnswer(BmsDxAnswer bmsDxAnswer,BmsDxComment bmsDxComment,BmsDxAnswer bmsDxAnswerByReply) {
        List<BmsDxComment> bmsDxComments = new LinkedList<>();
        bmsDxComments.add(bmsDxComment);
        BmsUserVideo bmsUserVideo = getBmsDxCommentsVideoMap(bmsDxComments);
        if(bmsUserVideo != null){
            if(bmsDxAnswer.getBmsUserId().intValue() == bmsUserVideo.getUserId().intValue()){
                //判断两个用户的端是否相同
                bmsDxAnswer.setIsAuthor(trueStatus);
            }
        }
        //设置是否是商家/是否是认证商家
        setIsBusinessAndBusinessAuth(bmsDxAnswer);
        setAnswerNickNameAndHeadImg(bmsDxAnswer);
        //查看是否有子评论
        if(bmsDxAnswerByReply != null){
            bmsDxAnswer.setAnswerNickName("");
            bmsDxAnswer.setAnswerUserRole(bmsDxAnswerByReply.getFromOrigin());
            bmsDxAnswer.setAnswerToUserId(bmsDxAnswerByReply.getBmsUserId());
            Integer userId = bmsDxAnswerByReply.getBmsUserId();
            if(bmsDxAnswerByReply.getFromOrigin() == Constants.USER_CLIENT) {
                BmsUser tmpBmsUser = TokenManager.getUser(userId);
                if (tmpBmsUser != null) {
                    bmsDxAnswer.setAnswerNickName(tmpBmsUser.getLoginName() == null ?
                            tmpBmsUser.getSystemUser().getLoginName() : tmpBmsUser.getLoginName());
                }
            }else if(bmsDxAnswerByReply.getFromOrigin() == Constants.BUSINESS_CLIENT){
                Integer businessId = bmsDxAnswerByReply.getBmsBusinessId();
                if(businessId != null){
                    Optional<BmsBusiness> businessOptional = bmsBusinessService.getBaseDao().findById(businessId);
                    if(businessOptional.isPresent()){
                        BmsBusiness business = businessOptional.get();
                        String loginName = business.getVendorName();
                        if(StringUtils.isNotBlank(loginName)){
                            bmsDxAnswer.setAnswerNickName(loginName);
                        }
                    }
                }
                bmsDxAnswer.setAnswerToUserId(bmsDxAnswerByReply.getBmsBusinessId());
            }
        }
    }
}
